package seatiger.tomcat.catalina.connector.http;

import seatiger.tomcat.catalina.connector.ResponseStream;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 处理Http1.1协议的的stream,如果返回报文头中没有使用Content-Length，那么使用chunk应答
 */
@Deprecated
public final class HttpResponseStream extends ResponseStream {

    //判断是否需要使用chunk
    private boolean useChunking;

    //使用这个字段防止递归调用
    private boolean writingChunk;

    public HttpResponseStream(HttpResponseImpl response) {
        super(response);
        checkChunking(response);
    }

    /**
     * 使用chunk一个字符一个字符写出去
     * 1\r\n
     * 一个字符的内容
     * 回车换行
     *
     * @param b
     * @throws IOException
     */
    @Override
    public void write(int b) throws IOException {
        if (useChunking && !writingChunk) {
            writingChunk = true;
            try {
                //这个方法最终也会调用 this.write(int b);
                //使用这个writingChunk 变量防止递归调用
                print("1\r\n");
                super.write(b);
                println();
            }finally {
                writingChunk = false;
            }
        }else{
            super.write(b);
        }
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        if (useChunking && !writingChunk) {
            if (len > 0) {
                writingChunk = true;
                try {
                    println(Integer.toHexString(len));
                    super.write(b, off, len);
                    println();
                }finally {
                    writingChunk = false;
                }
            }
        }else {
            super.write(b, off, len);
        }
    }

    /**
     * 判断是否需要使用chunk 应答
     * @param response
     */
    protected void checkChunking(HttpResponseImpl response) {
        useChunking = !response.isCommitted()
                        && response.getContentLength() == -1
                        && response.getStatus() != HttpServletResponse.SC_NOT_MODIFIED;
        if (useChunking) {
            response.setHeader("Transfer-Encoding", "chunked");
        }
    }

    @Override
    public void close() throws IOException {
        if (useChunking) {
            writingChunk = true;
            try {
                print("0\r\n\r\n");
            } finally {
                writingChunk = false;
            }
        }
        super.close();
    }
}
